package com.iot.sdk.config;

import com.dc3.common.constant.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author 咕唧
 * @Date 2022/7/28 16:28
 * @Version 1.0
 */
@Slf4j
@Configuration
public class RabbitmqConfig {

    @Value("${spring.application.name}")
    private String serviceName;


    @Bean
    RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        //这个是设置我们对外发送数据的时候将数据转成什么格式
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setReturnsCallback((message) -> {
            log.error("Send message({}) to exchange({}), routingKey({}) failed: {}", message.getMessage(), message.getExchange(), message.getRoutingKey(), message.getReplyText());
        });
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (!ack) {
                log.error("CorrelationData({}) ack failed: {}", correlationData, cause);
            }
        });
        return rabbitTemplate;
    }

    @Bean
    public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        //当我们收到消息的时候转成什么格式
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return factory;
    }



    //声明manager给我们返回数据的时候交换机和队列
    @Bean
    public TopicExchange metaDataExchange() {
        //durable指的是交换机持久化,并不会因为mq服务器的重启而消失,和消息没关系, 消息只能保存在队列中
        return new TopicExchange(CommonConstant.Rabbit.TOPIC_EXCHANGE_METADATA, true, false);
    }

    /**
     * 声明一个队列
     *
     * @return
     */
    @Bean
    public Queue metaDataQueue() {
        return new Queue(CommonConstant.Rabbit.ROUTING_DRIVER_METADATA_PREFIX + serviceName, true, false, false);
    }

    /**
     * 绑定声明的交换机和队列
     *
     * @param metaDataExchange
     * @param metaDataQueue
     * @return
     */
    @Bean
    public Binding bindingMetaData(TopicExchange metaDataExchange, Queue metaDataQueue) {
        return BindingBuilder
                .bind(metaDataQueue)
                .to(metaDataExchange)
                .with(CommonConstant.Rabbit.ROUTING_DRIVER_METADATA_PREFIX + serviceName);
    }
}
